import sys
from PyQt5.QtWidgets import (
    QApplication, QMainWindow, QDialog, QWidget, QVBoxLayout, QHBoxLayout,
    QFormLayout, QLineEdit, QPushButton, QCheckBox, QLabel, QListWidget,
    QTextEdit, QComboBox, QSplitter, QMessageBox, QTabWidget,QListWidgetItem,QStatusBar ,QFrame 
)
from PyQt5.QtCore import Qt, pyqtSignal, QObject, QSettings
from PyQt5.QtGui import QTextCursor
import paho.mqtt.client as mqtt
import binascii
import os
import configparser
from datetime import datetime
import random
import string
import json
import httpdef
#https://pyob.oxyry.com/
class MQTTSignals(QObject):
    connection_changed = pyqtSignal(bool)
    message_received = pyqtSignal(str, str, int, bytes)
    message_show = pyqtSignal(str)

class LoginDialog(QDialog):
    def __init__(self, client_name="", parent=None):
        super().__init__(parent)
        self.setWindowTitle("Connection Settings")
        self.setFixedSize(400, 400)
        self.setModal(True)
        
        self.client_name = client_name
        self.client = mqtt.Client()
        self.is_connected = False
        self.signals = MQTTSignals()
        
        self.config = configparser.ConfigParser()
        self.config_file = 'mqtt_config.ini'
        
        # 存储订阅主题的字典 {topic: qos}
        self.subscriptions = {}
        
        self.init_ui()
        self.load_settings()
        self.load_subscriptions()  # 加载保存的订阅主题

    def random_client_id(self, length=16):
        chars = string.ascii_letters + string.digits
        return ''.join(random.choices(chars, k=length))

    def init_ui(self):
        layout = QVBoxLayout(self)
        
        form_layout = QFormLayout()
        self.client_name_input = QLineEdit(self.client_name)
        form_layout.addRow("Client Name:", self.client_name_input)
        
        server_layout = QHBoxLayout()
        self.server_input = QLineEdit("")
        self.port_input = QLineEdit("1883")
        server_layout.addWidget(self.server_input)
        server_layout.addWidget(self.port_input)
        form_layout.addRow("Server:", server_layout)
        
        self.client_id_input = QLineEdit(self.random_client_id())
        form_layout.addRow("Client ID:", self.client_id_input)
        
        self.username_input = QLineEdit()
        form_layout.addRow("Username:", self.username_input)
        self.password_input = QLineEdit()
        self.password_input.setEchoMode(QLineEdit.Password)
        form_layout.addRow("Password:", self.password_input)

        
        # SSL/TLS配置
        self.ssl_checkbox = QCheckBox("SSL/TLS")
        self.ssl_checkbox.setEnabled(False)  # 禁用复选框

        self.ssl_checkbox.stateChanged.connect(self.toggle_ssl_options)
        form_layout.addRow(self.ssl_checkbox)
        
        # SSL扩展选项
        self.ssl_options = QWidget()
        ssl_options_layout = QVBoxLayout(self.ssl_options)
        
        # 证书验证选项
        verify_layout = QHBoxLayout()
        self.ssl_verify_check = QCheckBox("Verify Server Certificate")
        self.ssl_verify_check.setChecked(True)
        self.ssl_verify_check.stateChanged.connect(self.toggle_cert_verify)
        verify_layout.addWidget(self.ssl_verify_check)
        
        # 证书验证级别
        self.cert_reqs_combo = QComboBox()
        self.cert_reqs_combo.addItems(["Required", "Optional", "None"])
        self.cert_reqs_combo.setCurrentIndex(0)
        verify_layout.addWidget(QLabel("Level:"))
        verify_layout.addWidget(self.cert_reqs_combo)
        ssl_options_layout.addLayout(verify_layout)
        
        # CA证书路径
        self.ca_file_input = QLineEdit()
        ssl_options_layout.addWidget(QLabel("CA File (for verification):"))
        ssl_options_layout.addWidget(self.ca_file_input)
        
        # 客户端证书
        cert_layout = QHBoxLayout()
        self.client_cert_input = QLineEdit()
        cert_layout.addWidget(QLabel("Client Cert:"))
        cert_layout.addWidget(self.client_cert_input)
        ssl_options_layout.addLayout(cert_layout)
        
        # 客户端密钥
        key_layout = QHBoxLayout()
        self.client_key_input = QLineEdit()
        key_layout.addWidget(QLabel("Client Key:"))
        key_layout.addWidget(self.client_key_input)
        ssl_options_layout.addLayout(key_layout)
        
        self.ssl_options.setVisible(False)
        form_layout.addRow(self.ssl_options)

         
        
        # 自动连接和自动订阅选项
        self.auto_connect_check = QCheckBox("Auto Connect")
        self.auto_subscribe_check = QCheckBox("Auto Subscribe")
        option_layout = QHBoxLayout()
        option_layout.addWidget(self.auto_connect_check)
        option_layout.addWidget(self.auto_subscribe_check)
        form_layout.addRow("Options:", option_layout)
        
        layout.addLayout(form_layout)
        
        button_layout = QHBoxLayout()
        self.connect_btn = QPushButton("Connect")
        self.connect_btn.clicked.connect(self.toggle_connection)
        button_layout.addWidget(self.connect_btn)
        
        self.save_btn = QPushButton("Save Settings")
        self.save_btn.clicked.connect(self.save_settings)
        button_layout.addWidget(self.save_btn)
        
        layout.addLayout(button_layout)
        
        self.client.on_connect = self.on_connect
        self.client.on_disconnect = self.on_disconnect
    def toggle_cert_verify(self, state):
        """切换证书验证状态"""
        self.cert_reqs_combo.setEnabled(state == Qt.Checked)
        self.ca_file_input.setEnabled(state == Qt.Checked)

        
    def get_settings_dict(self):
        return {
            'client_name': self.client_name_input.text(),
            'server': self.server_input.text(),
            'port': self.port_input.text(),
            'client_id': self.client_id_input.text(),
            'username': self.username_input.text(),
            'password': self.password_input.text(),
            'ssl_enabled': str(self.ssl_checkbox.isChecked()),
            'ca_file': self.ca_file_input.text(),
            'client_cert': self.client_cert_input.text(),
            'client_key': self.client_key_input.text(),
            'auto_connect': str(self.auto_connect_check.isChecked()),
            'auto_subscribe': str(self.auto_subscribe_check.isChecked()),

            'ssl_enabled': str(self.ssl_checkbox.isChecked()),
            'ssl_verify': str(self.ssl_verify_check.isChecked()),
            'ssl_verify_level': str(self.cert_reqs_combo.currentIndex()),
            'ca_file': self.ca_file_input.text(),
            'client_cert': self.client_cert_input.text(),
            'client_key': self.client_key_input.text(),            

        }
        
    def save_settings(self):
        self.config.read(self.config_file)
        
        settings = self.get_settings_dict()
        client_name = settings['client_name']
        
        if (client_name != self.client_name and 
            self.config.has_section(client_name)):
            reply = QMessageBox.question(
                self, 'Confirm', 
                f"Client '{client_name}' already exists. Overwrite?",
                QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
            if reply == QMessageBox.No:
                return
        
        if self.client_name and self.client_name != client_name:
            self.config.remove_section(self.client_name)
            # 如果修改了客户端名称，也重命名订阅配置文件
            old_sub_file = f"subscriptions_{self.client_name}.ini"
            new_sub_file = f"subscriptions_{client_name}.ini"
            if os.path.exists(old_sub_file):
                os.rename(old_sub_file, new_sub_file)
        
        if not self.config.has_section(client_name):
            self.config.add_section(client_name)
        
        for key, value in settings.items():
            if key != 'client_name':
                self.config.set(client_name, key, value)
        
        with open(self.config_file, 'w') as configfile:
            self.config.write(configfile)
            
        self.client_name = client_name
        QMessageBox.information(self, "Success", "Settings saved successfully.")
        
    def load_settings(self, client_name=None):
        if not client_name:
            client_name = self.client_name
            
        if not os.path.exists(self.config_file):
            return
            
        self.config.read(self.config_file)
        if not self.config.has_section(client_name):
            return
            
        self.client_name_input.setText(client_name)
        self.server_input.setText(self.config.get(client_name, 'server', fallback=''))
        self.port_input.setText(self.config.get(client_name, 'port', fallback='1883'))
        self.client_id_input.setText(self.config.get(client_name, 'client_id', fallback=self.random_client_id()))
        self.username_input.setText(self.config.get(client_name, 'username', fallback=''))
        self.password_input.setText(self.config.get(client_name, 'password', fallback=''))
        
        #ssl_enabled = self.config.getboolean(client_name, 'ssl_enabled', fallback=False)
        #self.ssl_checkbox.setChecked(ssl_enabled)
        #self.toggle_ssl_options(Qt.Checked if ssl_enabled else Qt.Unchecked)
        
        #self.ca_file_input.setText(self.config.get(client_name, 'ca_file', fallback=''))
        #self.client_cert_input.setText(self.config.get(client_name, 'client_cert', fallback=''))
        #self.client_key_input.setText(self.config.get(client_name, 'client_key', fallback=''))

        # 加载SSL设置
        ssl_enabled = self.config.getboolean(client_name, 'ssl_enabled', fallback=False)
        self.ssl_checkbox.setChecked(ssl_enabled)
        self.toggle_ssl_options(Qt.Checked if ssl_enabled else Qt.Unchecked)
        
        ssl_verify = self.config.getboolean(client_name, 'ssl_verify', fallback=True)
        self.ssl_verify_check.setChecked(ssl_verify)
        
        verify_level = self.config.getint(client_name, 'ssl_verify_level', fallback=0)
        self.cert_reqs_combo.setCurrentIndex(verify_level)
        
        self.ca_file_input.setText(self.config.get(client_name, 'ca_file', fallback=''))
        self.client_cert_input.setText(self.config.get(client_name, 'client_cert', fallback=''))
        self.client_key_input.setText(self.config.get(client_name, 'client_key', fallback=''))
        
        # 根据加载的设置更新UI状态
        self.toggle_cert_verify(Qt.Checked if ssl_verify else Qt.Unchecked)

        
        auto_connect = self.config.getboolean(client_name, 'auto_connect', fallback=False)
        self.auto_connect_check.setChecked(auto_connect)
        
        auto_subscribe = self.config.getboolean(client_name, 'auto_subscribe', fallback=True)
        self.auto_subscribe_check.setChecked(auto_subscribe)
        
    def load_subscriptions(self):
        """加载保存的订阅主题"""
        if not self.client_name:
            return
            
        sub_file = f"subscriptions_{self.client_name}.ini"
        if not os.path.exists(sub_file):
            return
            
        sub_config = configparser.ConfigParser()
        sub_config.read(sub_file)
        
        if sub_config.has_section('subscriptions'):
            for topic, qos in sub_config.items('subscriptions'):
                self.subscriptions[topic] = int(qos)
    
    def save_subscriptions(self):
        """保存当前订阅主题到文件"""
        if not self.client_name:
            return
            
        sub_config = configparser.ConfigParser()
        sub_config['subscriptions'] = self.subscriptions
        
        sub_file = f"subscriptions_{self.client_name}.ini"
        with open(sub_file, 'w') as f:
            sub_config.write(f)
    
    def add_subscription(self, topic, qos):
        """添加订阅主题到列表"""
        self.subscriptions[topic] = qos
        self.save_subscriptions()
    
    def remove_subscription(self, topic):
        """从列表中移除订阅主题"""
        if topic in self.subscriptions:
            del self.subscriptions[topic]
            self.save_subscriptions()
    
    def toggle_ssl_options(self, state):
        self.ssl_options.setVisible(state == Qt.Checked)
        
    def toggle_connection(self):
        if self.connect_btn.text() == "Connect":
            self.connect_mqtt()
        else:
            self.disconnect_mqtt()
            
    def connect_mqtt(self):
        server = self.server_input.text()
        port = int(self.port_input.text())
        client_id = self.client_id_input.text() or None
        username = self.username_input.text() or None
        password = self.password_input.text() or None
        
        try:
            if self.ssl_checkbox.isChecked():
                # 设置TLS参数
                ca_certs = self.ca_file_input.text() if self.ssl_verify_check.isChecked() else None
                
                # 根据选择的验证级别设置cert_reqs
                cert_reqs = {
                    0: mqtt.ssl.CERT_REQUIRED,  # Required
                    1: mqtt.ssl.CERT_OPTIONAL,   # Optional
                    2: mqtt.ssl.CERT_NONE        # None
                }[self.cert_reqs_combo.currentIndex()]
                
                # 设置TLS
                self.client.tls_set(
                    ca_certs=ca_certs,
                    certfile=self.client_cert_input.text(),
                    keyfile=self.client_key_input.text(),
                    cert_reqs=cert_reqs,
                    tls_version=mqtt.ssl.PROTOCOL_TLS
                )
                
                # 如果禁用验证，设置不检查主机名
                if not self.ssl_verify_check.isChecked():
                    self.client.tls_insecure_set(True)
            
            if username and password:
                self.client.username_pw_set(username, password)
            
            self.client.connect(server, port)
            self.client.loop_start()
            self.connect_btn.setEnabled(False)
            self.connect_btn.setText("Connecting...")
        except Exception as e:
            #QMessageBox.critical(self, "Error", f"Connection failed: {str(e)}")
            self.reset_connection()
        
    def disconnect_mqtt(self):
        self.client.disconnect()
        self.client.loop_stop()
        self.reset_connection()
        self.signals.connection_changed.emit(False)
        
    def on_connect(self, client, userdata, flags, rc):
        if rc == 0:
            self.is_connected = True
            self.connect_btn.setText("Disconnect")
            self.signals.connection_changed.emit(True)
            
            # 连接成功后自动订阅保存的主题
            self.signals.message_show.emit(' 登录成功，已就绪 ')

            if self.auto_subscribe_check.isChecked() and self.subscriptions:
                for topic, qos in self.subscriptions.items():
                    self.client.subscribe(topic, qos)
        else:
            #QMessageBox.critical(self, "Error", f"Connection failed with code {rc}")       
            print("Error:", f"Connection failed with code {rc}") 
            self.signals.message_show.emit(' 登录失败，请检查输入信息是否正确 ')

            self.reset_connection()
        self.connect_btn.setEnabled(True)
        
    def on_disconnect(self, client, userdata, rc):
        self.reset_connection()
        self.signals.connection_changed.emit(False)
        self.signals.message_show.emit(' 已断开！ ')
    def reset_connection(self):
        self.is_connected = False
        self.connect_btn.setText("Connect")
        self.connect_btn.setEnabled(True)
        
class MQTTSignals2(QObject):
    connection_changed = pyqtSignal(bool)
    message_show = pyqtSignal(str)

class MQTTClientTab(QWidget):
    def __init__(self, client_name="", parent=None):
        super().__init__(parent)
        self.client_name = client_name
        self.login_dialog = LoginDialog(client_name)
        self.login_dialog.signals.connection_changed.connect(self.handle_connection_change)
        self.login_dialog.signals.message_show.connect(self.handle_msg_change)

        self.login_dialog.client.on_message = self.on_message
        

        self.signals = MQTTSignals2()
        
        self.init_ui()
        
        # 如果提供了客户端名称，尝试自动连接
        if client_name:
            self.login_dialog.load_settings(client_name)
            if self.login_dialog.config.has_section(client_name):
                if self.login_dialog.auto_connect_check.isChecked():
                    self.login_dialog.connect_mqtt()
                    
                    

        
    def init_ui(self):
        main_layout = QVBoxLayout(self)
        
        # 顶部工具栏
        toolbar = QHBoxLayout()
        
        # 显示客户端名称
        self.name_label = QLabel(self.client_name if self.client_name else "New Client")
        self.name_label.setStyleSheet("font-weight: bold;")
        toolbar.addWidget(self.name_label)
        
        # 状态指示灯
        self.status_indicator = QLabel()
        self.status_indicator.setFixedSize(16, 16)
        self.update_status_indicator(False)
        toolbar.addWidget(self.status_indicator)
        toolbar.addWidget(QLabel("Connection Status:"))
        
        # 连接设置按钮
        self.login_btn = QPushButton("Connection Settings")
        self.login_btn.clicked.connect(self.show_login_dialog)
        toolbar.addWidget(self.login_btn)
        
        toolbar.addStretch()
        main_layout.addLayout(toolbar)
        
        # 主界面区域
        main_splitter = QSplitter(Qt.Horizontal)
        main_splitter.setStyleSheet("""
            QSplitter::handle {
                background: #FF0000;
                width: 4px;
            }
        """)
        
        # 左侧订阅列表
        sub_list_widget = QWidget()
        sub_list_layout = QVBoxLayout(sub_list_widget)
        sub_list_layout.addWidget(QLabel("Subscribed Topics:"))
        self.subscription_list = QListWidget()
        self.subscription_list.itemDoubleClicked.connect(self.unsubscribe_topic)
        sub_list_layout.addWidget(self.subscription_list)
        main_splitter.addWidget(sub_list_widget)
        
        # 右侧主区域
        right_splitter = QSplitter(Qt.Vertical)
        
        # ================= 消息显示和订阅区域 =================
        msg_sub_widget = QWidget()
        msg_sub_layout = QVBoxLayout(msg_sub_widget)
        
        # 消息显示标签
        
        receive_label = QLabel("订阅选项")
        receive_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
        receive_label.setStyleSheet("""
            background-color: #FFD700;
            border: 1px solid #000000;
            border-radius: 3px;
            padding: 6px;
            font-size: 16px;
        """)
        
        
        msg_sub_layout.addWidget(receive_label)
        
        # 显示格式和清除按钮
        display_clear_layout = QHBoxLayout()
        display_clear_layout.addWidget(QLabel("Display Format:"))
        self.display_format_combo = QComboBox()
        self.display_format_combo.addItems(["Plain Text", "HEX"])
        display_clear_layout.addWidget(self.display_format_combo)
        clear_btn = QPushButton("Clear Messages")
        clear_btn.clicked.connect(self.clear_messages)
        display_clear_layout.addStretch()
        display_clear_layout.addWidget(clear_btn)
        msg_sub_layout.addLayout(display_clear_layout)
        
        # 接收消息框
        self.message_display = QTextEdit()
        self.message_display.setReadOnly(True)
        msg_sub_layout.addWidget(self.message_display)
        
        # 订阅主题部分
        sub_control_layout = QFormLayout()
        # 订阅输入行
        sub_input_layout = QHBoxLayout()
        self.sub_topic_input = QLineEdit()
        self.sub_qos_combo = QComboBox()
        self.sub_qos_combo.addItems(["0", "1", "2"])
        sub_input_layout.addWidget(self.sub_topic_input)
        sub_input_layout.addWidget(QLabel("QoS:"))
        sub_input_layout.addWidget(self.sub_qos_combo)
        sub_control_layout.addRow("Subscribe Topic:", sub_input_layout)
        # 订阅按钮
        self.sub_btn = QPushButton("Subscribe")
        self.sub_btn.clicked.connect(self.subscribe_topic)
        self.sub_btn.setEnabled(False)
        sub_control_layout.addRow(self.sub_btn)
        
        msg_sub_layout.addLayout(sub_control_layout)
        right_splitter.addWidget(msg_sub_widget)
        
        # ================= 发布消息区域 =================
        publish_widget = QWidget()
        publish_layout = QVBoxLayout(publish_widget)
        self.create_publish_ui(publish_layout)
        right_splitter.addWidget(publish_widget)
        
        main_splitter.addWidget(right_splitter)
        main_splitter.setSizes([int(self.width() * 0.33), int(self.width() * 0.67)])
        
        main_layout.addWidget(main_splitter)
        
        # 初始化订阅列表
        self.update_subscription_list()
         
    def create_publish_ui(self, layout):      
        label = QLabel("发布选项")
        label.setAlignment(Qt.AlignmentFlag.AlignCenter)
        label.setStyleSheet("""
            background-color: #FFD700;
            border: 1px solid #000000;
            border-radius: 3px;
            padding: 6px;
            font-size: 16px;
        """)
        
        layout.addWidget(label)    
        form_layout = QFormLayout()        
        # 发布主题
        self.pub_topic_input = QLineEdit()
        try:
            settings = QSettings("last_config.ini", QSettings.IniFormat)
            seg_key = f'{self.client_name}/last_publish'
            str_key = settings.value(seg_key, "")
            self.pub_topic_input.setText(str_key)
        except Exception as e:
            pass
        form_layout.addRow("Topic:", self.pub_topic_input)
        
        # 消息内容
        self.message_input = QTextEdit()
        self.message_input.setMaximumHeight(100)
        form_layout.addRow("Message:", self.message_input)
        
        # 发布选项
        option_layout = QHBoxLayout()
        self.pub_qos_combo = QComboBox()
        self.pub_qos_combo.addItems(["0", "1", "2"])
        self.hex_publish_check = QCheckBox("HEX Send")
        self.retain_check = QCheckBox("Retain")
        option_layout.addWidget(QLabel("QoS:"))
        option_layout.addWidget(self.pub_qos_combo)
        option_layout.addWidget(self.hex_publish_check)
        option_layout.addWidget(self.retain_check)
        form_layout.addRow(option_layout)
        
        # 发布按钮
        self.pub_btn = QPushButton("Publish")
        self.pub_btn.clicked.connect(self.publish_message)
        self.pub_btn.setEnabled(False)
        form_layout.addRow(self.pub_btn)
        
        layout.addLayout(form_layout)
    
    def show_login_dialog(self):
        self.login_dialog.exec_()
        if self.login_dialog.client_name:
            self.client_name = self.login_dialog.client_name
            self.name_label.setText(self.client_name)
            self.update_subscription_list()
    def handle_msg_change(self, str):
        print("MQTTClientTab handle_msg_change", str)
        self.signals.message_show.emit(str)
        pass
    def handle_connection_change(self, connected):
        self.sub_btn.setEnabled(connected)
        self.pub_btn.setEnabled(connected)
        self.update_status_indicator(connected)
        self.signals.connection_changed.emit(connected)
        
        
    def update_status_indicator(self, connected):
        color = "green" if connected else "red"
        self.status_indicator.setStyleSheet(f"""
            background-color: {color};
            border-radius: 8px;
            border: 1px solid dark{color};
        """)
        
    def update_subscription_list(self):
        """更新订阅列表显示"""
        self.subscription_list.clear()
        for topic, qos in self.login_dialog.subscriptions.items():
            item = QListWidgetItem(f"{topic} (QoS{qos})")
            item.setData(Qt.UserRole, topic)  # 存储原始topic
            self.subscription_list.addItem(item)
        
    def on_message(self, client, userdata, msg):
        self.login_dialog.signals.message_received.emit(
            msg.topic, 
            str(msg.qos),
            msg.retain,
            msg.payload
        )
        self.update_message_display(msg.topic, str(msg.qos), msg.retain, msg.payload)
    
    def update_message_display(self, topic, qos, retain, payload):
        now = datetime.now()
        milliseconds = now.microsecond // 1000
        timestamp = now.strftime(f"%Y-%m-%d %H:%M:%S.{milliseconds:03d}")
    
        display_format = self.display_format_combo.currentText()
        content = ""
        note = ""

        try:
            if display_format == "HEX":
                hex_str = binascii.hexlify(payload).decode('utf-8')
                content = ' '.join([hex_str[i:i+2] for i in range(0, len(hex_str), 2)])
            elif display_format == "Plain Text":
                content = payload.decode('utf-8')
            else:
                try:
                    content = payload.decode('utf-8')
                    if any(ord(c) < 32 and c not in '\n\t\r' for c in content):
                        raise UnicodeDecodeError('', b'', 0, 0, 'Contains control characters')
                except (UnicodeDecodeError, ValueError):
                    hex_str = binascii.hexlify(payload).decode('utf-8')
                    content = ' '.join([hex_str[i:i+2] for i in range(0, len(hex_str), 2)])
                    note = " (Auto detected HEX)"
        except Exception as e:
            hex_str = binascii.hexlify(payload).decode('utf-8')
            content = ' '.join([hex_str[i:i+2] for i in range(0, len(hex_str), 2)])
            note = f" (Decode Error: {str(e)})"

        retain_flag = "[Retain]" if retain else ""
        message = (f"[{topic}] QoS:{qos} {retain_flag} [{timestamp}] \n"
                   f"\n"
                   f"{content}{note}\n"
                   f"{'-'*50}\n")
        
        self.message_display.moveCursor(QTextCursor.End)
        self.message_display.insertPlainText(message)
        
    def subscribe_topic(self):
        topic = self.sub_topic_input.text().strip()
        qos = int(self.sub_qos_combo.currentText())
        if topic:
            # 检查是否已订阅
            if topic not in self.login_dialog.subscriptions:
                self.login_dialog.client.subscribe(topic, qos)
                self.login_dialog.add_subscription(topic, qos)
                self.update_subscription_list()
                #self.statusBar().showMessage(f"Subscribed to {topic} (QoS{qos})")
            else:
                #self.statusBar().showMessage(f"Already subscribed to {topic}")
                pass
            
    def unsubscribe_topic(self, item):
        """取消订阅主题"""
        topic = item.data(Qt.UserRole)
        reply = QMessageBox.question(
            self, 'Confirm', 
            f"Unsubscribe from '{topic}'?",
            QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
        
        if reply == QMessageBox.Yes:
            self.login_dialog.client.unsubscribe(topic)
            self.login_dialog.remove_subscription(topic)
            self.update_subscription_list()
            #self.statusBar().showMessage(f"Unsubscribed from {topic}")
            
    def publish_message(self):
        topic = self.pub_topic_input.text()
        message = self.message_input.toPlainText()
        qos = int(self.pub_qos_combo.currentText())
        retain = self.retain_check.isChecked()
        
        print('self.client_name:',self.client_name)
        settings = QSettings("last_config.ini", QSettings.IniFormat)
        seg_key = f'{self.client_name}/last_publish'
        settings.setValue(seg_key, topic)


        if not topic:
            QMessageBox.warning(self, "Warning", "Publish topic cannot be empty!")
            return
            
        try:
            if self.hex_publish_check.isChecked():
                payload = bytes.fromhex(message.replace(" ", ""))
            else:
                payload = message.encode('utf-8')
                
            self.login_dialog.client.publish(topic, payload, qos=qos, retain=retain)
            #self.statusBar().showMessage(f"Message published to {topic}")
        except ValueError:
            QMessageBox.critical(self, "Error", "Invalid HEX format!")
        except Exception as e:
            QMessageBox.critical(self, "Error", f"Publish failed: {str(e)}")
            
    def clear_messages(self):
        self.message_display.clear()

class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        
        self.status_bar = QStatusBar()
        self.setStatusBar(self.status_bar)  # 设置为主窗口的状态栏

        # 在状态栏显示消息
        self.status_bar.showMessage("")  # 显示3秒后消失
        self.status_bar.setStyleSheet("QStatusBar{ color: red; }")

        self.setWindowTitle("MQTT Client Pro")
        self.setGeometry(100, 100, 800, 600)
        
        self.init_ui()
        self.load_clients()
        #self.login_dialog.signals.connection_changed.connect(self.handle_connection_change)
    def init_ui(self):
        main_widget = QWidget()
        self.setCentralWidget(main_widget)
        main_layout = QVBoxLayout(main_widget)
        
        # 创建标签页
        self.tab_widget = QTabWidget()
        self.tab_widget.setTabsClosable(True)
        self.tab_widget.tabCloseRequested.connect(self.close_tab)
        
        # 添加标签按钮
        self.add_tab_btn = QPushButton("+")
        self.add_tab_btn.setFixedWidth(30)
        self.add_tab_btn.clicked.connect(self.add_new_tab)
        self.tab_widget.setCornerWidget(self.add_tab_btn, Qt.TopRightCorner)
        
        main_layout.addWidget(self.tab_widget)
        
        # 添加关于菜单
        menubar = self.menuBar()
        help_menu = menubar.addMenu("Help")
        about_action = help_menu.addAction("About")
        about_action.triggered.connect(self.show_about_dialog)
        
    def load_clients(self):
        """加载所有保存的客户端配置"""
        config = configparser.ConfigParser()
        config_file = 'mqtt_config.ini'
        
        if not os.path.exists(config_file):
            self.add_new_tab("Client 1")
            return
            
        config.read(config_file)
        
        for section in config.sections():
            self.add_new_tab(section)
            
        if self.tab_widget.count() == 0:
            self.add_new_tab("Client 1")
        
    def add_new_tab(self, name=None):
        if not name:
            existing_names = [self.tab_widget.tabText(i) for i in range(self.tab_widget.count())]
            base_name = "MQTT Client"
            i = 1
            while f"{base_name} {i}" in existing_names:
                i += 1
            name = f"{base_name} {i}"
            
        new_tab = MQTTClientTab(name)
        
        
        
        index = self.tab_widget.addTab(new_tab, name)
        self.tab_widget.setCurrentIndex(index)
        print('add_new_tab')
        new_tab.signals.connection_changed.connect(self.handle_connection_change)
        new_tab.signals.message_show.connect(self.handle_msg_change)

    def handle_msg_change(self, str):
        self.status_bar.showMessage(str)  # 显示3秒后消失

     
    def handle_connection_change(self, connected):
        print('connected:',connected)

        
        
    def close_tab(self, index):
        if self.tab_widget.count() > 1:
            widget = self.tab_widget.widget(index)
            if widget.login_dialog.is_connected:
                widget.login_dialog.disconnect_mqtt()
            widget.deleteLater()
            self.tab_widget.removeTab(index)
        else:
            QMessageBox.warning(self, "Warning", "At least one tab must remain open.")

            
    def show_about_dialog(self):
        try:
       
            
            email="447825337@qq.com"
            website ="www.baidu.com" 
            txt = "test" 
            tel = "186XXXXXXXX" 
            
            
            about_text = (
                f'<div style="min-width: 500px"> MQTT Client Pro            <br>'
                f"Version: 1.0.0 <br>"
                f"Contact Support:<br>"
                f"email: <a href='{email}'>{email}</a> <br>"
                f"website: <a href='{website}'>{website}</a> <br>"            
                f"简介:{txt}<br>"
                f"tel:{tel} <br>"            
                f"Copyright © 2023 LIZHU"
            )
            #msg_box.setStyleSheet("QMessageBox { min-width: 450px; }")
            msg_box = QMessageBox(self)
            msg_box.setWindowTitle("About")
            msg_box.setTextFormat(Qt.RichText)
            msg_box.setText(about_text)
            


            msg_box.setIcon(QMessageBox.Information)
            msg_box.addButton(QMessageBox.Ok)
            msg_box.exec_()                   
        except:            
            print('访问异常')
            
 
            

if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = MainWindow()
    window.show()
    sys.exit(app.exec_())